package com.situ.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.situ.config.JwtProperties;
import com.situ.context.BaseContext;
import com.situ.domain.entity.TUser;
import com.situ.domain.dto.ChangeUserPasswordDTO;
import com.situ.domain.dto.LogInDTO;
import com.situ.domain.dto.RegisterDTO;
import com.situ.domain.dto.UserInfoDTO;
import com.situ.ex.NotLoginException;
import com.situ.ex.UserException;
import com.situ.service.UserService;
import com.situ.utils.JwtUtil;
import com.situ.utils.Result;
import io.jsonwebtoken.Claims;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/user")
@Tag(name = "用户接口")
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    private final JwtProperties jwtProperties;

    /**
     * 用户注册
     * @param registerDTO
     * @return
     */
    @PostMapping("/register")
    @Operation(summary = "用户注册")
    public Result register(@RequestBody RegisterDTO registerDTO) {
        log.info("用户注册信息:{}", registerDTO);
        if (StrUtil.isBlankIfStr(registerDTO.getUsername())) {
            return Result.failure("用户名不能为空");
        }
        if (StrUtil.isBlankIfStr(registerDTO.getPassword())) {
            return Result.failure("密码不能为空");
        }
        if (StrUtil.isBlankIfStr(registerDTO.getPassword2())) {
            return Result.failure("确认密码不能为空");
        }
        userService.register(registerDTO);
        return Result.ok("注册成功");
    }

    /**
     * 用户登录
     * @param registerDTO
     * @return
     */
    @Operation(summary = "用户登录接口")
    @PostMapping("/login")
    public Result userLogin (@RequestBody LogInDTO logInDTO) {
        log.info("用户登录:{}", logInDTO);
        String token = userService.userLogin(logInDTO);
        Map<String,String> map = new HashMap<>();
        map.put("token", token);
        return Result.success(200, "登录成功", map);
    }


    /**
     * 检查token状态
     * @param token
     * @return
     */
    @Operation(summary = "检查token状态接口")
    @PostMapping("/checkToken")
    public Result checkToken(String token) {
        log.info("检查token:{}", token);
        Claims claims = null;
        try {
            claims =
                    JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
        }catch (Exception e) {
            throw new NotLoginException("用户未登录");
        }
        TUser user = null;
        user = userService.lambdaQuery()
                .eq(TUser::getUid,(Integer)claims.get("userId"))
                .eq(TUser::getIsDelete, 0)
                .one();
        if (user == null) {
            throw new NotLoginException("伪造的token");
        }
        TUser user1 = TUser
                .builder()
                .uid(user.getUid())
                .username(user.getUsername())
                .avatar(user.getAvatar())
                .build();
        return Result.success(200, "用户已登录", user1);
    }

    @Operation(summary = "修改用户密码接口")
    @PostMapping("/changeUserPassword")
    public Result changeUserPassword(@RequestBody ChangeUserPasswordDTO userPasswordDTO) {
        log.info("修改用户密码:{}", userPasswordDTO);
        if (!userPasswordDTO.getPassword().equals(userPasswordDTO.getPassword2())) {
            throw new UserException("两次密码不一致");
        }
        if (userPasswordDTO.getPassword().equals(userPasswordDTO.getOldPassword())) {
            throw new UserException("新密码不能与旧密码一致");
        }
        userService.changeUserPassword(userPasswordDTO);
        return Result.ok("修改密码成功");
    }


    @Operation(summary = "获取用户信息接口")
    @GetMapping("/getUserInfo")
    public Result getUserInfo () {
        UserInfoDTO userInfo = userService.getUserInfo();
        return Result.success(200, "获取用户信息成功", userInfo);
    }


    @Operation(summary = "修改用户信息接口")
    @PostMapping("/updateUserInfo")
    public Result updateUserInfo (@RequestBody UserInfoDTO userInfoDTO) {
        log.info("修改用户信息:{}", userInfoDTO);
        TUser tUser = new TUser();
        BeanUtil.copyProperties(userInfoDTO, tUser);
        tUser.setUid(BaseContext.getCurrentId());
        tUser.setModifiedTime(new Date());
        tUser.setModifiedUser(userInfoDTO.getUsername());
        userService.lambdaUpdate()
                .eq(TUser::getUid, BaseContext.getCurrentId())
                .update(tUser);
        return Result.ok("修改用户信息成功");
    }
}
